﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace M
{
	/// <summary>
	/// 提供支持Output输出的管理类型
	/// 类似提供一个管理池，以支持多个key的output输出
	/// </summary>
	internal class MOutputManager
	{
		#region Singleton
		private object mLocker = new object();
		/// <summary>
		/// 用于访问的管理实例
		/// </summary>
		public static readonly MOutputManager Manager = new MOutputManager();
		#endregion

		/// <summary>
		/// 【私有】构建一个管理类型实例
		/// 初始化Output名称管理集合
		/// </summary>
		private MOutputManager()
		{
			this.mOutputList = new Dictionary<string, MOuput>();
		}

		/// <summary>
		/// 设置输出动作
		/// </summary>
		/// <param name="outputAction"></param>
		public void SetOutputAction(Action<string, string> outputAction)
		{
			lock (this.mLocker)
			{
				this.mOutputAction = outputAction;
			}
		}
		/// <summary>
		/// 注册输出
		/// </summary>
		/// <param name="output">Output实例</param>
		/// <exception cref="ArgumentException">Output实例为空引用</exception>
		/// <exception cref="MException">Output名称已存在</exception>
		public void RegisterOutput(MOuput output)
		{
			MValidator.CheckForNullReference("Output", output);
			lock (this.mLocker)
			{
				if (this.mOutputList.ContainsKey(output.Key))
					throw new MException("Ouput实例名已存在，请重新指定");
				this.mOutputList.Add(output.Key, output);
			}
		}
		/// <summary>
		/// 写输出
		/// </summary>
		/// <param name="key">Output名称</param>
		/// <param name="output">Output内容</param>
		/// <exception cref="ArgumentException">
		/// key为空时，引发参数异常
		/// </exception>
		/// <exception cref="MException">未找到指定的Output</exception>
		public void WriteOutput(string key, string output)
		{
			MValidator.CheckForEmptyString("Output实例名", key);
			if (!this.mOutputList.ContainsKey(key))
				throw new MException("Ouput实例不存在，请先进行注册");
			if (this.mOutputAction != null)
				this.mOutputAction.Invoke(key, output);
		}

		/// <summary>
		/// 托管的输出方法
		/// </summary>
		private Action<string, string> mOutputAction = null;
		/// <summary>
		/// 存储多个Output的Key集合
		/// </summary>
		private Dictionary<string, MOuput> mOutputList = null;


	}
}
